package org.bdware.irp.irplib.core;

import org.bdware.irp.irplib.core.IrpMessage;
import org.bdware.irp.irplib.core.IrpMessageHeader;
import org.bdware.irp.irplib.core.IrpMessageCode;
import org.bdware.irp.irplib.exception.IrpMessageDecodeException;
import org.bdware.irp.irplib.util.GlobalUtils;

import com.nimbusds.jose.jwk.JWK;

import java.util.Map;

public class IrpRequest extends IrpMessage{
    public byte[] doid;
    public byte[][] doidValues = null;

    public boolean isAuthNeeded;
    public byte[][] requestedKeys = null;
    public byte[] address;
    public int createNumber = 0;
    public static final String DOID_DEFAULT = "doidForCreate";

    /**
     * Creates an IrpRequest.
     */
    public IrpRequest(int opCode, String doid) {
        super(opCode, IrpMessageCode.RC_RESERVED);
        //this.authInfo = authInfo;
        this.doid = GlobalUtils.encodeString(doid);
    }

    public IrpRequest(int opCode, byte[] doid) {
        super(opCode, IrpMessageCode.RC_RESERVED);
        //this.authInfo = authInfo;
        this.doid = doid;
    }

    public static IrpRequest newIrsResolveRequest(String doid, String[] keys) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_RESOLUTION_DOID, doid);
        req.isAuthNeeded = false;
        if(keys != null) {
            req.requestedKeys = new byte[keys.length][];
            for(int i = 0; i < keys.length; i++) {
                req.requestedKeys[i] = GlobalUtils.encodeString(keys[i]);
            }
        }
        return req;
    }


    public static IrpRequest newGrsResolveRequest(String doid, String[] keys) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_RESOLVE_GRS, doid);
        req.isAuthNeeded = false;
        if(keys != null) {
            req.requestedKeys = new byte[keys.length][];
            for(int i = 0; i < keys.length; i++) {
                req.requestedKeys[i] = GlobalUtils.encodeString(keys[i]);
            }
        }
        return req;
    }


    public static IrpRequest newGrsCreateRequest(String doi, Map<String,String> values, JWK jwk) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_CREATE_ORG_GRS, doi);
        if(values != null) {
            req.doidValues = fromMap2Byte(values);
        }
        if(jwk != null){
            req.isAuthNeeded = true;
            req.header.setCertifiedFlag(true);
            req.signMessage(jwk);
        }
        return req;
    }

    public static IrpRequest newIrsResolveRequest(byte[] doid, byte[][] keys) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_RESOLUTION_DOID, doid);
        req.requestedKeys = keys;
        return req;
    }

    public static IrpRequest newIrsCreateDoidRequest(Map<String,String> values, JWK jwk) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_CREATE_DOID, DOID_DEFAULT);
        if(values != null) {
            req.doidValues = fromMap2Byte(values);
        }
        req.isAuthNeeded = true;
        req.header.setCertifiedFlag(true);
        req.signMessage(jwk);
        return req;
    }

    public static IrpRequest newIrsCreateDoidRequest(byte[] doid, byte[][] values) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_CREATE_DOID, doid);
        req.doidValues = values;
        return req;
    }

    public static IrpRequest newIrsUpdateDoidRequest(String doid, Map<String,String> values, JWK jwk) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_UPDATE_DOID, doid);
        if(values != null) {
            req.doidValues = fromMap2Byte(values);
        }
        req.isAuthNeeded = true;
        req.header.setCertifiedFlag(true);
        req.signMessage(jwk);
        return req;
    }

    public static IrpRequest newIrsUpdateDoidRequest(byte[] doid, byte[][] values) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_UPDATE_DOID, doid);
        req.doidValues = values;
        return req;
    }

    public static IrpRequest newIrsDeleteDoidRequest(String doid, JWK jwk) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_DELETE_DOID, doid);
        req.isAuthNeeded = true;
        req.header.setCertifiedFlag(true);
        req.signMessage(jwk);
        return req;
    }

    public static IrpRequest newIrsDeleteDoidRequest(byte[] doid) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_DELETE_DOID, doid);
        return req;
    }

    public static IrpRequest newIrsBatchCreateDoidRequest(Map<String,String> values, int count, JWK jwk){
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_BATCH_CREATE_DOID, DOID_DEFAULT);
        if(values != null) {
            req.doidValues = fromMap2Byte(values);
        }
        req.createNumber = count;
        req.isAuthNeeded = true;
        req.header.setCertifiedFlag(true);
        req.signMessage(jwk);
        return req;
    }

    public static IrpRequest newIrsBatchCreateDoidRequest(int count, byte[][] values){
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_BATCH_CREATE_DOID, DOID_DEFAULT);
        req.doidValues = values;
        req.createNumber = count;
        return req;
    }

    public static IrpRequest newVerityIrsServerRequest (JWK jwk, String address) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_VERIFY_IRS, jwk.getKeyID());
        req.isAuthNeeded = true;
        req.header.setCertifiedFlag(true);
        req.address = GlobalUtils.encodeString(address);
        req.signMessage(jwk);
        return req;
    }
    public static IrpRequest newVerityIrsServerRequest (byte[] doid, byte[] address) {
        IrpRequest req = new IrpRequest(IrpMessageCode.OC_VERIFY_IRS, doid);
        req.address = address;
        return req;
    }

    public Map<String,String> getDoidValuesByMap() {
        Map<String,String> result = null;
        try{
            result = fromBytes2Map(this.doidValues);
        }
        catch(IrpMessageDecodeException e){
            e.printStackTrace();
        }

        return result;
    }

    public String getDoid() {
        return GlobalUtils.decodeString(this.doid);
    }

    public String getAddress() {
        return GlobalUtils.decodeString(this.address);
    }
}
